﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI.HtmlControls;
using System.Drawing;
using DataAccess;
using com.chttl.ienc.bean;
using java.util;
using Microsoft.Reporting.WebForms;
using System.IO;
using Ionic.Zip;

namespace iEN.Report
{
    public partial class DemandReport : System.Web.UI.Page
    {
        //初始頁面
        protected void Page_Load(object sender, EventArgs e)
        {
            //clear cache
            Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            if (!this.Page.IsPostBack)//先判斷是否已經登入過
            {
                if (Session["LoginName"] == null)
                {
                    Response.Write("<script>alert('請先登入！！');location.href='../Login.aspx';</script>");
                }

                //權限判斷
                //Operator : 可查詢、匯出、列印報表。   Session["SysAdmin"]=1
                //Director : 管理者，可使用所有功能。   Session["SysAdmin"]=2
                string sSysAdmin = Session["SysAdmin"].ToString();
                if (sSysAdmin != "1" && sSysAdmin != "2")
                {
                    ErrorMsg("您沒有使用此頁面的權限，請聯絡系統管理員！");
                    btnQuery.Visible = false;
                    return;
                }

                tbBgnDate.Text = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("yyyy/MM/dd");
                DateTime dtNextMonthFirstDay = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(1).Month, 1);
                tbEndDate.Text = new DateTime(DateTime.Now.Year, DateTime.Now.Month, dtNextMonthFirstDay.AddDays(-1).Day).ToString("yyyy/MM/dd");
                Session["FolderName"] = Session.SessionID.ToString();
                Intialize();    //初始化控制項
            }
        }

        /// <summary>
        /// 初始化控制項
        /// </summary>
        private void Intialize()
        {
            //取得大樓名稱
            ddlBuilding.Items.Clear();
            ddlBuilding.Items.Add("---");
            DataTable dtOrgGroup = new DBAccess().getOrgGroupTableByLevel(1);  //取得Level=1的大樓資訊
            for (int i = 0; i < dtOrgGroup.Rows.Count; i++)
            {
                ListItem li = new ListItem(dtOrgGroup.Rows[i]["_name"].ToString().Trim(), dtOrgGroup.Rows[i]["_id"].ToString());
                ddlBuilding.Items.Add(li);
            }
            ddlBuilding.SelectedIndex = 0;

            btnQuery.Attributes["onclick"] = ";document.getElementById('Loading').style.visibility='visible';";
        }

        /// <summary>
        /// 重新選擇大樓
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ddlBuilding_SelectedIndexChanged(object sender, EventArgs e)
        {
            //by 978
            //clear eMeterList
            eMeterList.Items.Clear();
            selectAllLabel.Text = "";
            selectAllBox.Checked = false;
            selectAllBox.Visible = false;
            exportList.SelectedIndex = -1;

            ddlFloor.Items.Clear();
            ddlFloor.Items.Add("---");
            if (ddlBuilding.SelectedItem.Text != "---")
            {
                string sID = ddlBuilding.SelectedItem.Value;
                DataTable dtOrgGroup = new DBAccess().getOrgGroupTableByLevel(2);  //取得Level=2的樓層資訊
                dtOrgGroup.DefaultView.Sort = " _name";
                dtOrgGroup = dtOrgGroup.DefaultView.ToTable();

                IEnumerable<DataRow> query = from r in dtOrgGroup.AsEnumerable()
                                             where sID.Contains(r.Field<Int32>("_parent_id").ToString())
                                             select r;
                foreach (DataRow r in query)
                {
                    ListItem li = new ListItem(r["_name"].ToString().Trim(), r["_id"].ToString());
                    ddlFloor.Items.Add(li);
                }
            }
            Panel4.Visible = false;
            Panel1.Visible = false;
        }

        /// <summary>
        /// 重新選擇樓層
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ddlFloor_SelectedIndexChanged(object sender, EventArgs e)
        {
            //by 978
            //clear eMeterList
            eMeterList.Items.Clear();
            selectAllLabel.Text = "";
            selectAllBox.Checked = false;
            selectAllBox.Visible = false;
            exportList.SelectedIndex = -1;

            if (ddlFloor.SelectedItem.Text != "---")
            {
                string sID = ddlFloor.SelectedItem.Value;

                //978
                int floorID = Convert.ToInt32(sID);
                DBAccess_CHTD dbAccess = new DBAccess_CHTD();
                DataTable dtDemand = dbAccess.GetPowerMeterWithDemand(floorID);
                //異常處理
                if (dbAccess.ErrMsg != string.Empty)
                {
                    ErrorMsg("Exception: " + dbAccess.ErrMsg);
                }
                else
                {
                    foreach (DataRow row in dtDemand.Rows)
                    {
                        ListItem li = new ListItem(row["_name"].ToString().Trim(), row["_id"].ToString());
                        //CheckBoxList
                        eMeterList.Items.Add(li);
                    }
                    //show CheckBox
                    selectAllBox.Visible = true;
                    eMeterList.Visible = true;
                }
            }
            Panel4.Visible = false;
            Panel1.Visible = false;
        }

        protected void btnQuery_Click(object sender, EventArgs e)
        {
            string meterList = "";

            try
            {
                lblStatus.Text = "";
                if (ddlBuilding.SelectedItem.Text == "---")
                {
                    ErrorMsg("請選擇欲查詢的大樓！"); 
                    return;
                }

                //978
                else if (ddlFloor.SelectedItem.Text.Equals("---"))
                {
                    ErrorMsg("請選擇欲查詢的樓層！");
                    return;
                }

                else
                {
                    meterList = getMeterList();
                    if (meterList.Equals(""))
                    {
                        ErrorMsg("請選擇欲查詢的電錶！");
                        return;
                    }
                    else
                    {
                        MeterWithDemandReport(meterList);
                        ScriptManager.RegisterStartupScript(this, this.GetType(), "HideLoading", ";document.getElementById('Loading').style.visibility='hidden';", true);
                    }
                }
            }
            catch (Exception ex)
            {
                lblStatus.Text += ex.Message;
                Panel4.Visible = false;
                Panel1.Visible = false;
            }
        }

        //978
        private string getMeterList()
        {
            string meterList = "";
            foreach (ListItem li in eMeterList.Items)
            {
                if (li.Selected == true)
                {
                    if (meterList.Equals(""))
                    {
                        meterList = li.Value;
                    }
                    else
                    {
                        meterList = meterList + "," + li.Value;
                    }
                }
            }
            return meterList;
        }

        //978
        private string getMeterNameList()
        {
            string meterNameList = "";
            foreach (ListItem li in eMeterList.Items)
            {
                if (li.Selected == true)
                {
                    if (meterNameList.Equals(""))
                    {
                        meterNameList = li.Text;
                    }
                    else
                    {
                        meterNameList = meterNameList + "," + li.Text;
                    }
                }
            }
            return meterNameList;
        }

        //by 978
        private void MeterWithDemandReport(string iMeter)
        {
            string sBuildingName = ddlBuilding.SelectedItem.Text;   //大樓名稱
            string sFloor = ddlFloor.SelectedItem.Text;
            string sBgnDate = tbBgnDate.Text;
            string sEndDate = tbEndDate.Text;
            DBAccess_CHTD dbAccess = new DBAccess_CHTD();

            DateTime dtBgnDate = DateTime.Parse(sBgnDate);
            dtBgnDate = new DateTime(dtBgnDate.Year, dtBgnDate.Month, dtBgnDate.Day, 0, 0, 0);
            DateTime dtEndDate = DateTime.Parse(sEndDate);
            dtEndDate = new DateTime(dtEndDate.Year, dtEndDate.Month, dtEndDate.Day, 23, 59, 59);

            if (dtBgnDate > dtEndDate)
            {
                ErrorMsg("查詢的起始時間需大於結束時間！");
                return;
            }

            DataTable dtDemand = dbAccess.GetDemandReport(iMeter, dtBgnDate, dtEndDate);
            //異常處理
            if (dbAccess.ErrMsg != string.Empty)
            {
                ErrorMsg("Exception: " + dbAccess.ErrMsg);
            }
            else
            {
                if (dtDemand.Rows.Count > 0)
                {
                    //ScriptManager.RegisterStartupScript(UpdatePanel1, UpdatePanel1.GetType(), "", "alert('Meter list: " + iMeter + ", begin:" + dtBgnDate + ", end: " + dtEndDate + "')", true);

                    ReportViewer1.Reset();
                    ReportViewer1.LocalReport.DataSources.Clear();
                    ReportViewer1.LocalReport.ReportPath = dbAccess.OutputRDLC(dtDemand);
                    //異常處理
                    if (dbAccess.ErrMsg != string.Empty)
                    {
                        ErrorMsg("Exception: " + dbAccess.ErrMsg);
                    }
                    else
                    {
                        ReportViewer1.LocalReport.SetParameters(QueryReportParameter(
                        "查詢日期:" + sBgnDate + "~" + sEndDate,
                        sBuildingName + "用電需量報表",
                        sFloor,
                        String.Format("{0:0.####}", 0),
                        String.Format("{0:0}", 0),
                        "日期時間"
                        ));
                        ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet_Data", dtDemand));
                        ReportViewer1.LocalReport.DisplayName = "用電需量報表";
                        ReportViewer1.Visible = true;
                        ReportViewer1.LocalReport.Refresh();
                        Panel4.Visible = true;
                        Panel1.Visible = true;
                    }
                }
                else
                {
                    Panel4.Visible = false;
                    Panel1.Visible = false;
                    ErrorMsg("該電錶查無資料，請檢視資料！");
                    return;
                }
            }
        }

        private ReportParameter[] QueryReportParameter(string sDate, string sReportName, string sRoom, string sTotalPower, string sTotalMoney, string sColumnName)
        {
            ReportParameter[] ReportParameter = new ReportParameter[6];
            ReportParameter[0] = new ReportParameter("Report_Parameter_Date", sDate);
            ReportParameter[1] = new ReportParameter("Report_Parameter_ReportName", sReportName);
            ReportParameter[2] = new ReportParameter("Report_Parameter_Room", sRoom);
            ReportParameter[3] = new ReportParameter("Report_Parameter_TotalPower", sTotalPower);
            ReportParameter[4] = new ReportParameter("Report_Parameter_TotalMoney", sTotalMoney);
            ReportParameter[5] = new ReportParameter("Report_Parameter_Column", sColumnName);
            return ReportParameter;
        }

        private void ErrorMsg(string Msg)
        {
            ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", ";alert('" + Msg + "');", true);
            return;
        }

        protected void selectAllBox_CheckedChanged(object sender, EventArgs e)
        {
            Panel4.Visible = false;
            Panel1.Visible = false;
            exportList.SelectedIndex = -1;
            ReportViewer1.Reset();

            if (selectAllBox.Checked == true)
            {
                foreach (ListItem li in eMeterList.Items)
                {
                    li.Selected = true;
                }
                selectAllLabel.Text = "已選取了" + eMeterList.Items.Count + "個電錶";
                selectAllLabel.ForeColor = Color.Red;
                selectAllLabel.Visible = true;
            }
            else
            {
                foreach (ListItem li in eMeterList.Items)
                {
                    li.Selected = false;
                }
                selectAllLabel.Text = "已取消全選";
                selectAllLabel.ForeColor = Color.Red;
                selectAllLabel.Visible = true;
            }
        }

        protected void eMeterList_SelectedIndexChanged(object sender, EventArgs e)
        {
            selectAllLabel.Text = "";
            selectAllBox.Checked = false;
            Panel4.Visible = false;
            Panel1.Visible = false;
            exportList.SelectedIndex = -1;
            ReportViewer1.Reset();
        }

        //報表匯出
        protected void btnExport_Click(object sender, EventArgs e)
        {
            string msg = "";
            string FolderPath = "";
            string sReportFormat = "";
            string sExtension = "";
            string sErrReport = "";
            string sReportFileName = "";
            string sBuildingName = "";
            string sFloor = "";

            if (exportList.SelectedIndex < 0)
            {
                ErrorMsg("請選擇欲匯出的格式！");
                return;
            }

            try
            {
                FolderPath = this.MapPath("./Temp/" + Session["FolderName"].ToString() + "/");

                switch (exportList.SelectedItem.Value)
                {
                    case "PDF":
                        msg = exportList.SelectedItem.Text;
                        sReportFormat = "pdf";
                        sExtension = "pdf";
                        break;
                    case "Tiff":
                        msg = exportList.SelectedItem.Text;
                        sReportFormat = "image";
                        sExtension = "tiff";
                        break;
                    case "HTML":
                        msg = exportList.SelectedItem.Text;
                        //先輸出成word，之後再轉成html
                        sReportFormat = "word";
                        sExtension = "doc";
                        break;
                    case "Excel":
                        msg = exportList.SelectedItem.Text;
                        sReportFormat = "excel";
                        sExtension = "xls";
                        break;
                    default:
                        msg = "Didn't select a export format yet!";
                        break;
                }
                sBuildingName = ddlBuilding.SelectedItem.Text;
                sFloor = ddlFloor.SelectedItem.Text;
                sReportFileName = sBuildingName + sFloor + ReportViewer1.LocalReport.DisplayName + "." + sExtension;
                if (!ExportReport(ReportViewer1, FolderPath, sReportFileName, sReportFormat))
                {
                    sErrReport += sReportFileName + "匯出失敗！";
                }
                else 
                {
                    FileProcess(FolderPath, sReportFileName, false);
                    //ScriptManager.RegisterStartupScript(UpdatePanel1, UpdatePanel1.GetType(), "", "alert('" + exportList.SelectedItem.Value + "報表匯出成功')", true);
                }
            }
            catch
            {
                ErrorMsg("匯出失敗！");
                return;
            }

        }

        /// <summary>
        /// 將ReportView的報告輸出成檔案
        /// </summary>
        /// <param name="ReportViewerExport"></param>
        /// <param name="absoluteFolderPath"></param>
        /// <param name="FileName"></param>
        /// <param name="ExportType"></param>
        /// <returns></returns>
        private bool ExportReport(ReportViewer ReportViewerExport, string absoluteFolderPath, string FileName, string ExportType)
        {
            try
            {
                if (!Directory.Exists(absoluteFolderPath))
                {
                    Directory.CreateDirectory(absoluteFolderPath);
                }

                string FilePath = absoluteFolderPath + FileName;
                Warning[] warnings;
                string[] streamids;
                string mimeType;
                string encoding;
                string filenameExtension;

                byte[] bytes = ReportViewerExport.LocalReport.Render(
                ExportType, null, out mimeType, out encoding, out filenameExtension,
                out streamids, out warnings);

                FileStream MyFileStream = new FileStream(FilePath, FileMode.Create);
                long FileSize;
                FileSize = MyFileStream.Length;
                MyFileStream.Write(bytes, 0, (int)bytes.Length);
                MyFileStream.Flush();
                MyFileStream.Close();

                //選擇輸出HTML時，會先輸出成word，須再轉成html
                if (ExportType == "word")
                {
                    ExportLib.TransferDocToHTML(FilePath);
                }

                return true;
            }
            catch (Exception ex)
            {
                //lblStatus.Text += ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 資料夾所有檔案壓縮，或資料夾所有檔案導出下載
        /// </summary>
        /// <param name="absoluteFolderPath"></param>
        /// <param name="FullFileName"></param>
        /// <param name="IsCompress"></param>
        private void FileProcess(string absoluteFolderPath, string FullFileName, bool IsCompress)
        {
            try
            {
                if (Directory.Exists(absoluteFolderPath))
                {
                    if (!IsCompress)  //不壓縮打包 
                    {
                        string[] FileNamePath = Directory.GetFiles(absoluteFolderPath);
                        for (int i = 0; i < FileNamePath.Length; i++)
                        {
                            ScriptManager.RegisterStartupScript(this, this.GetType(), "output" +
                                i.ToString(), ";window.open('./Download.aspx?FilePath=" +
                                Server.UrlEncode(FileNamePath[i]) + "','Window" + i.ToString() + "');", true);
                        }
                    }
                    else//壓縮打包
                    {
                        string[] FileNamePath = Directory.GetFiles(absoluteFolderPath);
                        if (FileNamePath.Length == 0)
                            return;

                        using (ZipFile zip = new ZipFile(System.Text.Encoding.Default))
                        {
                            for (int i = 0; i < FileNamePath.Length; i++)
                            {
                                zip.AddFile(FileNamePath[i], "files");
                            }
                            zip.Save(absoluteFolderPath + FullFileName);
                        }
                        //刪除檔案
                        for (int i = 0; i < FileNamePath.Length; i++)
                        {
                            File.Delete(FileNamePath[i]);
                        }
                        ScriptManager.RegisterStartupScript(this, this.GetType(), "output1",
                        ";window.open('./Download.aspx?FilePath=" + Server.UrlEncode(absoluteFolderPath + FullFileName) + "','Window1')", true);
                    }
                }
            }
            catch (Exception ex)
            {
                //lblStatus.Text += ex.Message;
                return;
            }
        }
    }
}